package logica.pessoa;

import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import util.Endereco;

import logica.util.Data;

/**
 * Objeto que representa pessoas fisicas, sendo um pouco mais especifico que
 * a classe Pessoa em si.
 * @author Equipe Localisa (Usa quem precisa!)
 */
public class PessoaFisica extends Pessoa implements Serializable{
	
	private transient static final long serialVersionUID = 1L;
	protected  String CPF;
	protected  String RG;
	protected  Data dataDeNascimento;
	protected  String naturalidade;
	protected Endereco endereco;
	
	public PessoaFisica(){

		super();
		this.CPF = null;
		this.RG = null;
		this.dataDeNascimento = null;
		this.naturalidade = null;
		this.endereco = null;

	}
	
	/**
	 * @return O CPF da pessoa fisica
	 */
	public String getCPF() {
		return CPF;
	}
	
	/**
	 * Muda o CPF da pessoa fisica
	 * @param cpf O novo CPF
	 * @throws Exception Se o novo CPF nao for valido (nao estiver
	 * de acordo com o formato especificado no sistema)
	 */
	public void setCPF(String cpf) throws Exception {	
		if (! validaCPF(cpf)) {
			throw new Exception("\n\t<CPF invalido!>");
		}
		this.CPF = cpf;
	}
	
	/**
	 * @return O RG da pessoa fisica
	 */
	public String getRG() {
		return RG;
	}
	
	/**
	 * Muda o RG da pessoa fisica
	 * @param rg O novo RG 
	 * @throws Exception Se o  novo RG nao for valido (nao estiver
	 * de acordo com o formato especificado no sistema) 
	 */
	public void setRG(String rg) throws Exception {
		if (! validaRG(rg))  {
			throw new Exception("\n\t<RG invalido!>");
		}
		this.RG = rg;
	}
	
	/**
	 * @return A data de nascimento da pessoa fisica
	 */
	public Data getDataDeNascimento() {
		return dataDeNascimento;
	}
	
	/**
	 * Muda a data de nascimento da pessoa fisica
	 * @param dataDeNascimento A nova data de nascimento
	 * @throws Exception Se a nova data de nascimento nao for valida (nao estiver
	 * de acordo com o formato especificado no sistema)
	 */
	public void setDataDeNascimento(Data dataDeNascimento) throws Exception {
		if (dataDeNascimento == null) {
			throw new Exception("\n \t <Data invalida!>");
		}
		this.dataDeNascimento = dataDeNascimento;
	}
	
	/**
	 * @return A naturalidade da pessoa fisica
	 */
	public String getNaturalidade() {
		return naturalidade;
	}
	
	/**
	 * Muda a naturalidade da pessoa fisica
	 * @param naturalidade A nova naturalidade
	 * @throws Exception Se a  nova naturalidade nao for valida (nao estiver
	 * de acordo com o formato especificado no sistema)
	 */
	public void setNaturalidade(String naturalidade) throws Exception{
		if (naturalidade == null || naturalidade.trim().isEmpty()) {
			throw new Exception("\n\t<Naturalidade invalida!>");
		}
		this.naturalidade = naturalidade;
	}
        
	/**
	* Valida o CPF, verificando se ele eh composto apenas por numeros,
	* tendo exatamente 11 digitos numericos, podendo ou nao ter pontos entre
	* os os tres blocos iniciais de 3 digitos e um hifen antes dos dois ultimos
	* digitos
	*/

	private boolean validaCPF(String cpf) {
		if (cpf == null || cpf.trim().isEmpty()) {
			return false;
		}
		
		Pattern pCpf = Pattern.compile("[0-9]{3}([.])?[0-9]{3}([.])?[0-9]{3}([-])?[0-9]{2}");
		
		Matcher mCpf = pCpf.matcher(cpf);
		
		return mCpf.matches();
		
	}

        /**
	* Valida o RG, verificando se possui entre 7 e 15 digitos e se possui
	* apenas caracteres nao-numericos
	*/
        
	private boolean validaRG(String rg) throws Exception{
		if ( rg == null || rg.trim().isEmpty()) {
			return false;
		}
		
		Pattern pRg = Pattern.compile("[0-9]{7,15}");
		
		Matcher mRg = pRg.matcher(rg);
		
		return mRg.matches();
			
	}
	
	/**
	 * Compara um objeto PessoaFisica com um outro, verificando se
	 * seus atributos CPF e RG sao iguais
	 * @return True se os objetos sao iguais e False caso contrario
	 */
	@Override 
	public boolean equals(Object obj) {
		if (!(obj instanceof Pessoa)){
			return false;			
		}
		return (((PessoaFisica)obj).getCPF().replace(".","").replace("-","").equals(CPF.replace(".","").replace("-","")) 
				|| ((PessoaFisica)obj).getRG().equals(RG));
	}

}